import { View, Text } from '@tarojs/components';
import dayjs, { Dayjs } from 'dayjs';
import { useEffect, useMemo, useState } from 'react';
import classNames from 'classnames';
import './index.scss';
import { ArrowDown, ArrowUp } from '@nutui/icons-react-taro';

type DayStatus = {
  status?: 'checked-in' | 'disabled' | 'task' | string;
  extraText?: string;
};

// 日期标记：用于在日期下方绘制 1-3 个小点
type MarksMap = Record<string, number>;

type Props = {
  value?: Dayjs; // 'YYYY-MM-DD'
  onChange?: (val: string) => void;
  dataMap?: Record<string, DayStatus>; // 后端提供的状态数据映射
  marks?: MarksMap; // 日期的小点标记数量
};

const PREFIX_CLASS = 'm-calendar';
export default function Calendar({
  value = dayjs(),
  onChange,
  dataMap = {},
  marks = {},
}: Props) {
  const [currentMonth, setCurrentMonth] = useState(
    dayjs(value).startOf('month'),
  );
  const [selected, setSelected] = useState(dayjs(value));
  const [collapsed, setCollapsed] = useState(true);

  // 当展开时，页面滚动自动折叠
  useEffect(() => {
    if (collapsed) return;
    // 仅在 H5 环境可用，避免小程序报错
    if (typeof document === 'undefined') return;
    const container = document.querySelector(
      '.g-basic-layout-body',
    ) as HTMLElement | null;
    const target: HTMLElement | Window = container || window;

    let lastTop = container?.scrollTop ?? window.scrollY ?? 0;
    let ticking = false;

    const handleScroll = () => {
      if (ticking) return;
      ticking = true;
      requestAnimationFrame(() => {
        const currentTop = container?.scrollTop ?? window.scrollY ?? 0;
        if (currentTop > lastTop + 2 || currentTop > 8) {
          setCollapsed(true);
        }
        lastTop = currentTop;
        ticking = false;
      });
    };

    target.addEventListener('scroll', handleScroll, { passive: true } as any);
    return () => {
      target.removeEventListener('scroll', handleScroll as any);
    };
  }, [collapsed]);

  // 生成一个月的日期格子
  const days = useMemo(() => {
    const start = currentMonth.startOf('month').startOf('week');
    const end = currentMonth.endOf('month').endOf('week');

    const list: Dayjs[] = [];
    let d = start;
    while (d.isBefore(end) || d.isSame(end, 'day')) {
      list.push(d);
      d = d.add(1, 'day');
    }
    return list;
  }, [currentMonth]);

  // 折叠时只显示当前选中日期那一行
  const visibleDays = useMemo(() => {
    if (!collapsed) return days;
    const weekStart = selected.startOf('week');
    const weekEnd = selected.endOf('week');
    return days.filter(
      (d) => d.isSameOrAfter(weekStart) && d.isSameOrBefore(weekEnd),
    );
  }, [collapsed, days, selected]);

  const onSelect = (date: dayjs.Dayjs) => {
    if (dataMap[date.format('YYYY-MM-DD')]?.status === 'disabled') return;
    setSelected(date);
    setCurrentMonth(date.startOf('month')); // 切月
    onChange?.(date.format('YYYY-MM-DD'));
  };

  const renderDayContent = (date: dayjs.Dayjs) => {
    const dateStr = date.format('YYYY-MM-DD');
    const extraText = dataMap[dateStr]?.extraText || '';
    const dots = Math.max(0, Math.min(3, Number(marks[dateStr]) || 0));

    return (
      <View className="day-content">
        <Text className="day-number">{date.date()}</Text>
        {dots > 0 ? (
          <View className="day-dots">
            {Array.from({ length: dots }).map((_, idx) => (
              <View key={idx} className="day-dot" />
            ))}
          </View>
        ) : null}
        {extraText && <Text className="day-extra">{extraText}</Text>}
      </View>
    );
  };

  return (
    <View className={PREFIX_CLASS}>
      {/* 标题 */}
      <View className="calendar-header">
        <Text onClick={() => setCurrentMonth((m) => m.subtract(1, 'month'))}>
          ←
        </Text>
        <Text className="calendar-title">
          {currentMonth.format('YYYY年MM月')}
        </Text>
        <Text onClick={() => setCurrentMonth((m) => m.add(1, 'month'))}>→</Text>
      </View>

      {/* 周标题 */}
      <View className="calendar-weekdays">
        {['日', '一', '二', '三', '四', '五', '六'].map((w) => (
          <Text key={w} className="weekday">
            {w}
          </Text>
        ))}
      </View>

      {/* 日期格子 */}
      <View className="calendar-grid">
        {visibleDays.map((date) => {
          const dateStr = date.format('YYYY-MM-DD');
          const isSelected = selected.isSame(date, 'day');
          const isCurrentMonth = date.month() === currentMonth.month();
          const isToday = date.isSame(dayjs(), 'day');
          const status = dataMap[dateStr]?.status;

          return (
            <View
              key={dateStr}
              className={classNames('calendar-day', {
                selected: isSelected,
                today: isToday,
                'not-current': !isCurrentMonth,
                disabled: status === 'disabled',
                'checked-in': status === 'checked-in',
                task: status === 'task',
              })}
              onClick={() => onSelect(date)}
            >
              {renderDayContent(date)}
            </View>
          );
        })}
      </View>

      {/* 折叠按钮 */}
      <View className="calendar-toggle" onClick={() => setCollapsed((c) => !c)}>
        {collapsed ? <ArrowDown /> : <ArrowUp />}
      </View>
    </View>
  );
}
